#include <iostream>
#include <string>
#include <memory>

class Fruit
{
public:
    virtual void show() = 0;
};

class Apple : public Fruit
{
public:
    void show() override
    {
        std::cout << "我是一个苹果" << std::endl;
    }
};
class Banana : public Fruit
{
public:
    void show() override
    {
        std::cout << "我是一个香蕉" << std::endl;
    }
};

class Animal
{
public:
    virtual void voice() = 0;
};

class Lamp : public Animal
{
public:
    void voice() { std::cout << "咩咩咩\n"; }
};
class Dog : public Animal
{
public:
    void voice() { std::cout << "汪汪汪\n"; }
};

class Factory
{
public:
    virtual std::shared_ptr<Fruit> getFruit(const std::string &name) = 0;
    virtual std::shared_ptr<Animal> getAnimal(const std::string &name) = 0;
};

class FruitFactory : public Factory
{
public:
    virtual std::shared_ptr<Animal> getAnimal(const std::string &name)
    {
        return std::shared_ptr<Animal>();
    }
    virtual std::shared_ptr<Fruit> getFruit(const std::string &name)
    {
        if (name == "苹果")
        {
            return std::make_shared<Apple>();
        }
        else if (name == "⾹蕉")
        {
            return std::make_shared<Banana>();
        }
        return std::shared_ptr<Fruit>();
    }
    // virtual std::shared_ptr<Fruit> create() = 0;
    //  static std::shared_ptr<Fruit> create(const std::string &name)
    //  {
    //      if (name == "苹果")
    //          return std::make_shared<Apple>();
    //      else
    //          return std::make_shared<Banana>();
    //  }
};

class AnimalFactory : public Factory
{
public:
    virtual std::shared_ptr<Fruit> getFruit(const std::string &name)
    {
        return std::shared_ptr<Fruit>();
    }

    virtual std::shared_ptr<Animal> getAnimal(const std::string &name)
    {
        if (name == "⼩⽺")
        {
            return std::make_shared<Lamp>();
        }
        else if (name == "⼩狗")
        {
            return std::make_shared<Dog>();
        }
        return std::shared_ptr<Animal>();
    }
};

class FactoryProducer
{
public:
    static std::shared_ptr<Factory> getFactory(const std::string &name)
    {
        if (name == "动物")
        {
            return std::make_shared<AnimalFactory>();
        }
        else
        {
            return std::make_shared<FruitFactory>();
        }
    }
};
int main()
{
    std::shared_ptr<Factory> fruit_factory = FactoryProducer::getFactory("⽔果");
    std::shared_ptr<Fruit> fruit = fruit_factory->getFruit("苹果");
    fruit->show();
    fruit = fruit_factory->getFruit("⾹蕉");
    fruit->show();
    std::shared_ptr<Factory> animal_factory = FactoryProducer::getFactory("动物");
    std::shared_ptr<Animal> animal = animal_factory->getAnimal("⼩⽺");
    animal->voice();
    animal = animal_factory->getAnimal("⼩狗");
    animal->voice();
    return 0;
}

// class AppleFactory : public FruitFactory
// {
//     std::shared_ptr<Fruit> create() override
//     {
//         return std::make_shared<Apple>();
//     }
// };

// class BananaFactory : public FruitFactory
// {
//     std::shared_ptr<Fruit> create() override
//     {
//         return std::make_shared<Banana>();
//     }
// };

// int main()
// {

//     // fruit->show();
//     // fruit = FruitFactory::create("⾹蕉");ll

//     // fruit->show();

//     std::shared_ptr<FruitFactory> factory(new AppleFactory());
//     std::shared_ptr<Fruit> fruit = factory->create();
//     fruit->show();
//     factory.reset(new BananaFactory());
//     fruit = factory->create();
//     fruit->show();

//     return 0;
// }
